Nyc buildings¶
In [1]:
import holoviews as hv
import colorcet as cc
import datashader as ds
import spatialpandas as spd
import spatialpandas.io
from dask.diagnostics import ProgressBar
from holoviews.operation.datashader import (
rasterize, datashade, inspect_poly
)
hv.extension('bokeh')
In [2]:
ddf = spd.io.read_parquet_dask('./data/nyc_buildings.parq').persist()
Now we compute the top categories and drop everything else:
In [3]:
cats = list(ddf.type.value_counts().compute().iloc[:10].index.values) + ['unknown']
ddf['type'] = ddf.type.replace({None: 'unknown'})
ddf = ddf[ddf.type.isin(cats)]
ddf['type'] = ddf['type'].astype('category').cat.as_known()
with ProgressBar():
ddf = ddf.build_sindex().persist()
Next we build a legend for the categories and declare a tile source as backdrop:
In [4]:
colors = cc.glasbey_bw_minc_20_maxl_70
color_key = {cat: tuple(int(e*255.) for e in colors[i]) for i, cat in enumerate(cats)}
legend = hv.NdOverlay({k: hv.Points([0,0], label=str(k)).opts(
color=cc.rgb_to_hex(*v), size=0, apply_ranges=False)
for k, v in color_key.items()}, 'Type')
tiles = hv.element.tiles.CartoLight().opts(
min_height=800, responsive=True, xaxis=None, yaxis=None)
Now we put it all together, declaring a Polygons element from our data, datashade them and use the inspect_poly operation to allow us to hover on the data:
In [5]:
polys = hv.Polygons(ddf, vdims='type')
shaded = datashade(polys, color_key=color_key, aggregator=ds.by('type', ds.any()))
hover = inspect_poly(shaded).opts(fill_color='red', tools=['hover'])
tiles * shaded * legend * hover
Out[5]:
Finally we will plot each category of buildings separately:
In [6]:
hv.NdLayout({
cat: hv.element.tiles.CartoLight() * rasterize(polys.select(type=cat), aggregator='any') for cat in cats
}, 'Type').opts('Image', width=250, height=400, xaxis=None, yaxis=None).cols(4)
Out[6]: